package dyyx.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs;

import dyyx.dto.NodeData;
import dyyx.dto.WebResult;

public abstract class ZkViewWebUtil {

	private static final Set<String> OPS = new HashSet<>();

	private static final String OP_CONNECT = "connect";
	private static final String OP_DIS_CONNECT = "disConnect";
	private static final String OP_CLIENT_INFO = "clientInfo";
	private static final String OP_DATA = "data";
	private static final String OP_CHILD = "child";
	private static final String OP_CHILD_AND_SELF= "childAndSelf";

	
	private static final String OP_CREATE = "create";
	private static final String OP_UPDATE = "update";
	private static final String OP_DELETE= "delete";

	
	private static final Map<String,CreateMode> createModeMap = new HashMap<>();



	static {
		
		createModeMap.put("PERSISTENT", CreateMode.PERSISTENT);
		createModeMap.put("PERSISTENT_SEQUENTIAL", CreateMode.PERSISTENT_SEQUENTIAL);
		createModeMap.put("EPHEMERAL", CreateMode.EPHEMERAL);
		createModeMap.put("EPHEMERAL_SEQUENTIAL", CreateMode.EPHEMERAL_SEQUENTIAL);


		OPS.add(OP_CONNECT);
		OPS.add(OP_DIS_CONNECT);
		OPS.add(OP_CLIENT_INFO);
		OPS.add(OP_DATA);
		OPS.add(OP_CHILD);
		OPS.add(OP_CREATE);
		OPS.add(OP_UPDATE);
		OPS.add(OP_DELETE);
		OPS.add(OP_CHILD_AND_SELF);

		


	}
	
	public static boolean isListView(String op){
		if(OP_DATA.equals(op)){
			return true;
		}
		if(OP_CHILD.equals(op)){
			return true;
		}
		if(OP_CHILD_AND_SELF.equals(op)){
			return true;
		}
		return false;
	}

	public static void run(HttpServletRequest request, WebResult webResult) throws Exception {
		try {
			run_(request, webResult);
		} catch (Throwable e) {
			webResult.msg = webResult.op + " error," + e;
		}
	}
	
	

	private static void run_(HttpServletRequest request, WebResult webResult) throws Exception {
		String op = WebUtil.get(request, "op");
		String path = WebUtil.get(request, "path");
		String connstr = WebUtil.get(request, "connstr");
		String data = WebUtil.get(request, "data");
		byte[] bytes = null;
		if(data!=null){
			bytes = data.getBytes("utf8");
		}
		String versionstr = WebUtil.get(request, "version");
		int version = -1;
		if(!StringUtils.isBlank(versionstr)){
			version = WebUtil.getInt(request, "version");
		}
		String createModeStr = WebUtil.get(request, "createMode");
		
		CreateMode createMode = createModeMap.get(createModeStr);
		if(createMode==null){
			createMode = CreateMode.PERSISTENT;
		}
		

		if (StringUtils.isBlank(op)) {
			webResult.msg = "op blank";
			return;
		}
		if (!OPS.contains(op)) {
			webResult.msg = "op error";
			return;
		}
		webResult.op = op;

		if (OP_CONNECT.equals(op)) {

			if (StringUtils.isBlank(connstr)) {
				webResult.msg = "connstr blank";
				return;
			}

			ClientUtil.connect(connstr);
			Thread.sleep(500);

			webResult.msg = op + ",isConnected="+ClientUtil.isConnected()+"," + ClientUtil.getClientInfo();

			return;
		}

		if (OP_DIS_CONNECT.equals(op)) {

			ClientUtil.disconnect();

			webResult.msg = op + " success";

			return;
		}

		if (OP_CLIENT_INFO.equals(op)) {

			// ZkClient zkClient = ClientUtil.getZkClient();
			Map<String, Object> map = ClientUtil.getClientInfo();
			webResult.msg = map+"";
			return;
		}

		//

		if (OP_DATA.equals(op)) {

			if (StringUtils.isBlank(path)) {
				webResult.msg = "path blank";
				return;
			}

			NodeData nodeData = ClientUtil.getData(path);
			List<NodeData> list = new ArrayList<>();
			list.add(nodeData);
			webResult.list = list;

			return;
		}

		if (OP_CHILD.equals(op)) {

			if (StringUtils.isBlank(path)) {
				webResult.msg = "path blank";
				return;
			}
			List<NodeData> list = ClientUtil.getChildData(path);
			
			// NodeData nodeData = ClientUtil.getData(path);
			// list.add(0, nodeData);
			
			webResult.list = list;

			return;
		}
		
		if (OP_CHILD_AND_SELF.equals(op)) {

			if (StringUtils.isBlank(path)) {
				webResult.msg = "path blank";
				return;
			}
			List<NodeData> list = ClientUtil.getChildData(path);
			
			NodeData nodeData = ClientUtil.getData(path);
			list.add(0, nodeData);
			
			webResult.list = list;

			return;
		}
		
		
		
		
		
		if (OP_CREATE.equals(op)) {

			if (StringUtils.isBlank(path)) {
				webResult.msg = "path blank";
				return;
			}
			if(!ClientUtil.canModify(path)){
				webResult.msg = "create only for path start with /dyyx";
				return;
			}
 			// ZooDefs.Ids.OPEN_ACL_UNSAFE , This is a completely open ACL
			// 
			
			ClientUtil.getZkClient().zk.create(path, bytes, ZooDefs.Ids.OPEN_ACL_UNSAFE, createMode);
			
			webResult.msg = op +" done,createMode="+createMode.toString()+",data="+data;
			
			return;
		}
		
		if (OP_UPDATE.equals(op)) {

			if (StringUtils.isBlank(path)) {
				webResult.msg = "path blank";
				return;
			}
			if(!ClientUtil.canModify(path)){
				webResult.msg = "UPDATE only for path start with /dyyx";
				return;
			}
 			
			// byte[] bytes = LocalDateTime.now().toString().getBytes("utf8");
			ClientUtil.getZkClient().zk.setData(path,bytes , version);
			
			webResult.msg = op +" done,version="+version+",data="+data;
			
			return;
		}
		
		if (OP_DELETE.equals(op)) {

			if (StringUtils.isBlank(path)) {
				webResult.msg = "path blank";
				return;
			}
			if(!ClientUtil.canModify(path)){
				webResult.msg = "DELETE only for path start with /dyyx";
				return;
			}
 			
			// byte[] bytes = LocalDateTime.now().toString().getBytes("utf8");
			// ClientUtil.getZkClient().zk.setData(path,bytes , version);
			ClientUtil.getZkClient().zk.delete(path, version);
			
			webResult.msg = op +" done,version="+version+",data="+data;
			
			return;
		}


	}
	
	

}
